home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
utils
/
spr_cut
/
cutlst.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-11
|
9KB
|
406 lines
/* ---------------------------------------------------- */
/* SPRITE CUTTER UTILITY v2.0 */
/* by gaggi@cs.unibo.it */
/* ---------------------------------------------------- */
/* CUTLST.C */
/* sprite cut management module */
/* ---------------------------------------------------- */
#include <alloc.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include "mouse.h"
#include "graph13h.h"
/* ---------------------------------------------------- */
#include "interfac.h"
#include "cutlst.h"
#include "picview.h"
extern void error(unsigned, char *);
extern void xor_rect(unsigned, unsigned, unsigned, unsigned, unsigned );
extern void prepare_buffer(struct CUT *, unsigned char far *);
/* ---------------------------------------------------- */
#define MEM_ERR 1
#define FILE_ERR 2
#define LOAD_ERR 3
#define SOURCE_ERR 4
#define CUT_COLOR 0x04
#define CUT_SIZE sizeof(struct CUT) - sizeof(struct CUT *)
/* ------------- Public Datas ------------------------- */
struct CUT *cut_list; /* Dynamic list containing all the cuts */
picture source_pic; /* Source picture datas: palette and bitmap */
char source_name[MAXSTRINGLEN]; /* File name of the source picture */
unsigned char cut_x_size= 0x08, cut_y_size= 0x08; /* Sizes of the sprite */
/* ------------- Static datas ------------------------- */
static unsigned list_modified= 0;
static char lst_msg[]= "List modified.\rSave(y/n)?";
static char IO_prompt[]= "LST name ...";
static char SPR_prompt[]= "SPR file name ...";
/* ------------- static functions -------------------- */
static int load_cuts(int handle)
/* Loads the list of cuts from file */
{
struct CUT *crsr, **last= &cut_list;
register unsigned ret_val= 0;
while ( !eof(handle) )
{
if ( !(*last= crsr= (struct CUT *)malloc(sizeof(struct CUT))) )
{
error(MEM_ERR, NULL);
ret_val= -1;
break;
};
if ( read(handle, crsr, CUT_SIZE) != CUT_SIZE )
{
ret_val= -1;
error(LOAD_ERR, NULL);
break;
};
last= &(crsr->next);
}
if (*last) *last= NULL;
close(handle);
list_modified= 0;
Draw_cuts();
return ret_val;
}
static int write_cuts(FILE *dest)
/* Writes the list of cuts to a file */
{
struct CUT *crsr= cut_list;
while (crsr)
{
fwrite(crsr, CUT_SIZE, 1, dest);
crsr= crsr->next;
};
list_modified= 0;
return fclose(dest);
}
static void cut_number(unsigned x, unsigned y, unsigned number)
/* Puts the ordinal number of cut on the screen at coordinates x, y */
{
char temp[3];
Curcol= 0;
Draw_box(x + 1, y + 1, 15, 7);
Curcol= 15;
sprintf(temp, "%d", number);
OutText(x, y, temp);
}
static void renumber_cut(struct CUT *start, unsigned counter)
/* Renumbers all the cuts starting from the cut pointed by *start */
/* and the number counter. */
{
unsigned char far *buffer;
register unsigned temp1= start->width;
register unsigned temp2= start->height;
if (temp1 < 16 || temp2 < 16) /* if the cut sizes are too small */
{ /* the result of restoring image data */
Show_picture(&source_pic, NO_SET);/* to cancel cut number is unreadable */
Draw_cuts(); /* so I redraw picture and all */
return; /* the cuts */
};
if (!(buffer= (char far *)farmalloc(temp1*temp2 + 2*sizeof(unsigned))))
/* If there's not enough memory just draw a black bar to cancel cut */
/* number ... */
{
Curcol= 0;
Draw_box(start->x + 1, start->y + 1, 15, 7);
}
else { /* ... otherwise restore the original picture pixels */
((unsigned far *)buffer)[0]= temp1; /* Type cast on a Lvalue... ARGH! */
((unsigned far *)buffer)[1]= temp2; /* Davoli, please forgive me! */
prepare_buffer(start, buffer);
put_area(start->x, start->y, buffer);/* Restores original image datas */
farfree(buffer);
};
start= start->next;
while (start) /* Now change the number of all remaining cuts */
{
cut_number(start->x, start->y, counter++);
start= start->next;
};
}
/* ------------- public functions ------------------- */
int load_source(char *file_name)
{
char *temp;
if (cut_list) save_LST(1);
temp= (char *)malloc(MAXSTRINGLEN);
if (file_name) strcpy(temp, file_name);
else if (Input_box("PCX file name ...", temp, MAXSTRINGLEN - 1, 30, 80) <= 0)
{
free(temp);
return -1;
};
switch ( PCX_load(temp, &source_pic) )
{
case 1:
error(FILE_ERR, temp);
free(temp);
return -1;
case EOF:
case 2:
error(LOAD_ERR, NULL);
*source_name= 0;
destroy_LST();
clear_video(0);
free(temp);
return -1;
};
destroy_LST();
strcpy(source_name, temp);
mouse_cursor(OFF);
Show_picture(&source_pic, SET);
mouse_cursor(ON);
free(temp);
return 0;
}
int cut_sprite(unsigned click_x, unsigned click_y)
/* Adds a cut to the current list of cuts if the cut is not present yet */
/* otherwise it cancels the cut renumbering all the list */
{
struct CUT *crsr= cut_list,
*last= NULL;
register unsigned counter= 0;
asm sti
mouse_cursor(OFF);
if (!*source_name) return SOURCE_ERR; /* There's not source picture */
xor_rect(click_x, click_y, cut_x_size, cut_y_size, CUT_COLOR);
/* Xors the cut on the screen */
/* So if it is present yet it will be cancelled */
/* else it will be drawn */
while (crsr)
{
if (crsr->x == click_x && crsr->y == click_y && crsr->width == cut_x_size
&& crsr->height == cut_y_size) /* if the cut is present ... */
{
if (last) last->next= crsr->next; /* ... unlink it from the list */
else cut_list= crsr->next;
renumber_cut(crsr, counter); /* and renumber all the remaining */
free(crsr);
break;
};
last= crsr;
crsr= crsr->next;
counter++;
}
if (!crsr) /* if the cut is not present ... */
{ /* ... add it on the list queue */
if ( !(crsr= (struct CUT *)malloc(sizeof(struct CUT))) )
{
mouse_cursor(ON);
while (Mouse.Button);
return MEM_ERR;
};
if (last) last->next= crsr;
else cut_list= crsr;
crsr->next= NULL;
crsr->x= click_x;
crsr->y= click_y;
crsr->width= cut_x_size;
crsr->height= cut_y_size;
cut_number(click_x, click_y, counter);
};
list_modified= 1;
mouse_cursor(ON);
while (Mouse.Button);
return 0;
}
int save_LST(unsigned ask)
{
char *temp;
FILE *dest;
if ( ask && ( !list_modified || Message_box(lst_msg, 60, 80, 1) <= 0 ) )
return 0;
if (!cut_list) return 0;
temp= (char *)malloc(MAXSTRINGLEN);
if (Input_box(IO_prompt, temp, MAXSTRINGLEN - 1, 10, 80) <= 0)
{
free(temp);
return 0;
};
dest= fopen(temp, "wb");
free(temp);
fwrite(source_name, sizeof(source_name), 1, dest);
return write_cuts(dest);
}
int load_LST()
{
char *temp= (char *)malloc(MAXSTRINGLEN);
register int handle;
save_LST(1);
if (Input_box(IO_prompt, temp, MAXSTRINGLEN - 1, 10, 80) <= 0)
{
free(temp);
return 0;
};
if ( (handle= open(temp, O_RDWR | O_BINARY)) == -1 )
{
error(FILE_ERR, temp);
free(temp);
return -1;
};
read(handle, temp, MAXSTRINGLEN);
if ( load_source(temp) ) {
free(temp);
return -1;
};
free(temp);
destroy_LST();
return load_cuts(handle);
}
int save_SPR()
/* Writes all the sprites' bitmaps to a file */
{
FILE *spr_file;
char *temp;
unsigned char far *base;
struct CUT *crsr;
register unsigned row, col;
if (!cut_list) return -1;
temp= (char *)malloc(MAXSTRINGLEN);
if (Input_box(SPR_prompt, temp, MAXSTRINGLEN - 1, 10, 80) <= 0)
{
free(temp);
return 0;
};
spr_file= fopen(temp, "wb");
free(temp);
crsr= cut_list;
while (crsr)
{
fwrite(&crsr->height, sizeof(unsigned char), 2, spr_file);
base= &(source_pic.buffer[crsr->x + crsr->y * 320]);
for (row= 0; row < crsr->height; row++)
{
for (col= 0; col < crsr->width; col++)
putc(base[col],spr_file);
base += 320;
};
crsr= crsr->next;
};
return fclose(spr_file);
}
void destroy_LST()
{
struct CUT *crsr= cut_list, *next;
while (crsr)
{
next= crsr->next;
free(crsr);
crsr= next;
};
cut_list= NULL;
}
void Draw_cuts()
{
struct CUT *crsr= cut_list;
register unsigned counter= 0;
mouse_cursor(OFF);
while (crsr)
{
xor_rect(crsr->x, crsr->y, crsr->width, crsr->height, CUT_COLOR);
cut_number(crsr->x, crsr->y, counter++);
crsr= crsr->next;
};
mouse_cursor(ON);
}